<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
<script>
// Promise承诺
// Promise用来解决异步编程的问题

// Promise三种状态：
// 进行中
// 成功
// 失败

// Promise状态改变：
// 从 进行中 改变为 成功
// 从 进行中 改变为 失败

// Promise对象的状态只能改变一次！

// 在执行器函数中改变Promise对象状态的行为：
// 1.执行rosolve函数，Promise对象改变为成功状态，结果为resolve的参数
// 2.执行reject函数，Promise对象改变为失败状态，结果为reject的参数
// 3.出现异常情况时，Promise对象的状态改变为失败，结果为异常信息

// 成功或失败的回调函数中改变Promise对象状态的行为：
// 1.返回非Promise对象值时，Promise对象状态改变为成功，结果为返回的值
// 2.返回Promise对象值时，Promise对象状态和结果跟随返回的Promise对象
// 3.出现异常情况时，Promise对象的状态改变为失败，结果为异常信息

// Promise对象的then方法
// 用于指定Promise对象成功和失败的回调函数，返回一个新的Promise对象

// Promise对象的catch方法
// 用于捕获错误、指定Promise对象失败的回调函数，返回一个新的Promise对象

// Promise对象的finally方法
// 用于指定最后执行的回调函数

// Promise的静态方法
// let p4 = Promise.all([p1,p2,p3]);
// p1,p2,p3都成功时，p4成功，结果为p1,p2,p3的结果的数组
// p1,p2,p3任意一个失败时，p4失败，结果为p1,p2,p3失败的那个结果

// let p4 = Promise.race([p1,p2,p3]);
// p4的状态和结果跟随p1,p2,p3最先完成那个

// let p1 = Promise.resolve(参数);
// 如果参数为非Promise对象时，p1为成功状态，结果为参数值
// 如果参数为Promise对象时，p1的状态和结果跟随参数

// let p1 = Promise.reject(参数);
// p1为失败状态，结果为参数


// async函数（异步函数）
// async函数内部有异步操作，执行后返回Promise对象
// async函数返回的Promise对象的状态和结果：
// 1.返回非Promise对象值时，Promise对象状态改变为成功，结果为返回的值
// 2.返回Promise对象值时，Promise对象状态和结果跟随返回的Promise对象
// 3.出现异常情况时，Promise对象的状态改变为失败，结果为异常信息

// await等待
// await会等待后面表达式的值（通常是Promise对象）
// await必须在async函数中使用
// await后面的Promise对象为失败状态时（未处理失败状态），async函数执行结束，剩余程序不执行
// 在async函数中执行到await时，会跳出当前函数执行流（暂停执行），等到async函数后面的同步程序执行完成后，再回到async函数中执行剩余的程序
// console.log( 1 )
// async function fn(){
//     console.log( 2 )
//     await new Promise((resolve,reject)=>{
//         resolve(3)
//     })
//     console.log( 4 )
// }
// let p1 = fn()
// p1.then(()=>{
//     console.log( 5 )
// })
// console.log( 6 )
// 1 2 6 4 5


// 事件循环机制
// JS脚本在浏览器中如何执行的（同步和异步之间如何执行）

// 浏览器渲染进程中的主要线程：
// 1.GUI渲染线程，主要负责页面渲染
// 2.JS引擎线程，主要负责解析执行JS脚本
// GUI渲染线程和JS引擎线程是互斥的关系
// 'JS脚本会阻塞页面渲染'
// 3.事件触发线程，主要负责事件触发和回调函数的管理
// 事件队列（任务队列），里面放着可以执行的异步任务的回到函数
// 4.计时器线程，主要负责给某个函数计时
// 5.异步http请求线程，主要负责等待异步请求状态改变

// 当一段脚本要执行时：
// 1.JS引擎先解析这段代码，将同步程序加入执行栈并按顺序执行
// 2.JS引擎遇到异步程序时，不会等待异步程序完成并执行回到函数，异步程序的回调函数将会被加入事件队列
// 3.JS引擎执行完同步程序之后（空闲），会从事件队列中取出排在前面的回调函数加入执行栈调用
// 4.回调函数被调用时，内部如果又有同步和异步程序，重复上述 1 2 3 步骤，如此反复循环即 事件循环

// 不同的异步任务分为 微任务 和 宏任务
// 微任务：Promise
// 宏任务：其他异步任务
// 优先执行 微任务，然后再依次执行 宏任务

</script>
</body>
</html>